﻿using Microsoft.Win32;
using SecurityApp.Classes;
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace SecurityApp
{

    public partial class CryptoWindow : Window
    {
        static int intTijd;
        static Boolean isDecryptie, isAborted;
        static String strUitvoer, strSleutel, strLocatie;
        public BackgroundWorker bwProces = new BackgroundWorker();
        static System.Timers.Timer tmrElapsed = new System.Timers.Timer();
        OpenFileDialog ofdOpenen = new OpenFileDialog();

        public CryptoWindow()
        {
            InitializeComponent();
            isAborted = false;

            // Bij elke tick tmr_Tick() uitvoeren om de 100ms
            tmrElapsed.Interval = 100;
            tmrElapsed.Elapsed += new ElapsedEventHandler(tmr_Tick);

            // BackgroundWorker configureren
            bwProces.WorkerReportsProgress = true;
            bwProces.DoWork += new DoWorkEventHandler(bw_DoWork);
            bwProces.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        #region ### Blader knop ###

        private void btnBladeren_Click(object sender, RoutedEventArgs e)
        {
            txtLocatie.Clear();
            txtOutput.Text = "";
            // Dialoogvenster openen om een bestand te selecteren + filter instellen
            ofdOpenen.Filter = "Alle bestanden (.*)|*.*";
            Boolean blnDialogResult = (Boolean) ofdOpenen.ShowDialog();
            
            // Nagaan of er een bestand geselecteerd is
            if (blnDialogResult)
            {
                txtLocatie.Text = ofdOpenen.FileName;
                strLocatie = ofdOpenen.FileName;
            }
        }

        #endregion

        #region ### Encrypteer & Decrypteer knop ###

        private void btnEncrypteren_Click(object sender, RoutedEventArgs e)
        {
            // Nagaan of de sleutel uit 24 karakters bestaat en of er een bestand geselecteerd is
            if (controleerBestand() && controleerSleutel() && !Crypto.isWeakKey(txtSleutel.Text))
            {
                disableControls();
                strSleutel = txtSleutel.Text;
                txtOutput.Text = "";
                isDecryptie = false;
                buzzyCircle.Visibility = Visibility.Visible;
                strUitvoer = ofdOpenen.FileName.Replace(".", "_encryp.");
                bwProces.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("Gelieve elk veld correct in te vullen.\nMogelijk is de sleutel onveilig.", "Foutieve invoer!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void btnDecrypteren_Click(object sender, RoutedEventArgs e)
        {
            // Nagaan of de sleutel uit 24 karakters bestaat en of er een bestand geselecteerd is
            if (controleerBestand() && controleerSleutel() && ! Crypto.isWeakKey(txtSleutel.Text))
            {
                disableControls();
                strSleutel = txtSleutel.Text;
                txtOutput.Text = "";
                isDecryptie = true;
                buzzyCircle.Visibility = Visibility.Visible;
                strUitvoer = ofdOpenen.FileName.Replace(".", "_decryp.");
                bwProces.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("Gelieve elk veld correct in te vullen.\nMogelijk is de sleutel onveilig.", "Foutieve invoer!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        #endregion

        #region ### BackgroundWorker ###

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            // Tijd op 0 zetten en timer starten
            intTijd = 0;
            tmrElapsed.Start();

            // Het bestand uitlezen en omzetten naar binair
            String binaireInvoer = FileIO.bestandNaarBinair(strLocatie);

            // Starten van de versleuteling of ontcijfering
            String binaireUitvoer = Crypto.tripleDES_Encrypt(binaireInvoer, isDecryptie);

            if (binaireUitvoer.Equals("abort"))
            {
                isAborted = true;
            }
            else
            {
                // Het bestand wegschrijven
                FileIO.binairNaarBestand(strUitvoer, binaireUitvoer);
            }

            // Proces is afgelopen -> timer stoppen
            tmrElapsed.Stop();

        }

        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            enableControls();
            buzzyCircle.Visibility = Visibility.Hidden;

            if (isAborted)
            {
                txtOutput.Inlines.Clear();
                txtOutput.Inlines.Add(new Run("Het proces is niet voltooid."));
                txtOutput.Inlines.Add(new Run("\nEr deed zich een onverwachte fout voor."));
            }
            else
            {
                txtOutput.Inlines.Clear();
                txtOutput.Inlines.Add(new Run("Het proces is voltooid en duurde "));
                txtOutput.Inlines.Add(new Run((intTijd / 10f) + "") { Foreground = Brushes.DarkBlue });
                txtOutput.Inlines.Add(new Run(" seconden.\n\nDe uitvoer is opgeslagen onder de volgende naam:\n"));
                txtOutput.Inlines.Add(new Run(strUitvoer.Substring(strUitvoer.LastIndexOf("\\") + 1)) { Foreground = Brushes.DarkBlue });
            }

        }

        private void tmr_Tick(object sender, EventArgs e)
        {
            intTijd++;
        }

        #endregion

        #region ### Disable/Enable controls ###

        private void disableControls()
        {
            txtLocatie.IsEnabled = false;
            txtSleutel.IsEnabled = false;
            btnBladeren.IsEnabled = false;
            btnEncrypteren.IsEnabled = false;
            btnDecrypteren.IsEnabled = false;
        }

        private void enableControls()
        {
            txtLocatie.IsEnabled = true;
            txtSleutel.IsEnabled = true;
            btnBladeren.IsEnabled = true;
            btnEncrypteren.IsEnabled = true;
            btnDecrypteren.IsEnabled = true;
        }

        #endregion

        #region ### Controle Methodes ###

        private bool controleerSleutel()
        {
            // Eén ascii = 8 bits lang. 24 tekens * 8 =192bits (= sleutel lengte)
            if (txtSleutel.Text.Length == 24)
            {
                return true;
            }
            else
            {
                MessageBox.Show("De sleutel moet 24 tekens lang zijn.", "Foutieve sleutel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return false;
            }
        }

        private bool controleerBestand()
        {
            if (txtLocatie.Text == "")
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        private void txtSleutel_KeyDown(object sender, KeyEventArgs e)
        {
            if (txtSleutel.Text.Length < 24)
            {
                    e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }

        #endregion

        private void Window_Closing_1(object sender, CancelEventArgs e)
        {
            Start window = new Start();
            window.Show();
        }

    }
}
